<template>
  <div class="top-nav">
    <div class="city-choose">{{city}}</div>
    <el-input
      v-model="searchCity"
      style="width: 240px;"
      size="large"
      placeholder="搜索城市"
      :prefix-icon="Search"
      @keyup.enter="searchCityHandler"
    >
    </el-input>
    <el-select
      v-model="drawType"
      placeholder="请选择"
      style="width: 240px;"
      size="large"
      @change="drawTypeHandler"
    >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
        >
      </el-option>
    </el-select>
    <el-select
      v-model="iconType"
      placeholder="请选择"
      style="width: 240px;"
      size="large"
    >
      <el-option v-for="item in icons" :key="item.value" :label="item.label" :value="item.value"></el-option>
    </el-select>
  </div>
  <div id="map-container"></div>
  <div id="pupop" v-html="popupContent"></div>
</template>

<script setup lang="js">
import { Search } from '@element-plus/icons-vue'
import { onMounted, ref } from 'vue'
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import { XYZ } from 'ol/source'
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import GeoJSON from 'ol/format/GeoJSON'
import Style from 'ol/style/Style'
import Stroke from 'ol/style/Stroke'
import Fill from 'ol/style/Fill'
import Draw from 'ol/interaction/Draw'
import Overlay from 'ol/Overlay'

const GAODEKEY = '6ba06ce041c1809fcbd1887418323435'

const searchCity = ref('')
const drawType = ref('')
const iconType = ref('')
const adcode = ref('')
const city = ref('')
const popupContent = ref('')
const cityLocation = ref([])

const options = [
  { label: '直线', value: 'line' },
  { label: '圆形', value: 'circle' },
  { label: '多边形', value: 'polygon' },
  { label: '自由画笔', value: 'freehand' },
  { label: '清楚绘图', value: 'clear' },
]

const icons = [
  { label: '充电站', value: 'charging-station' },
  { label: '公交站', value: 'bus-station' },
  { label: '停车场', value: 'parking' },
  { label: '推出标记', value: 'exit' },
]

let map, popup, cityLayer, draw, drawLayer;

const searchCityHandler = async () => {
  const allLayers = map.getLayers()
  let _cityLayer =allLayers.getArray().filter(layer => layer.getClassName() === 'city-layer')
  console.log(_cityLayer)
  if(_cityLayer.length > 0) {
    _cityLayer.forEach(layer => {
      map.removeLayer(layer)
    })
  }
  const temp = await fetch(`https://restapi.amap.com/v3/geocode/geo?key=${GAODEKEY}&address=${searchCity.value}`)
  const res = await temp.json()
  if(res.status === '0') return alert('未找到该城市')
  adcode.value = res.geocodes[0].adcode
  searchCity.value = city.value = res.city
  cityLocation.value = res.geocodes[0].location.split(',').map(Number)
  setTimeout(() => {
    cityLayer = new VectorLayer({
      className: 'city-layer',
      source: new VectorSource({
        url: `https://geo.datav.aliyun.com/areas_v3/bound/${adcode.value}.json`,
        format: new GeoJSON()
      }),
      style: new Style({
        stroke: new Stroke({
          color: 'black',
          widthL: 2
        }),
        fill: new Fill({
          color: 'rgba(255, 0, 0, 0.5)'
        })
      })
    })
    map.addLayer(cityLayer)
    if(cityLocation.value) {
      map.getView().animate({
        center: cityLocation.value,
        zoom: 8,
        duration: 2000
      })
    }
  })
}

const drawTypeHandler = async (type) => {
  if(drawType.value === 'clear') {
    drawLayer.getSource().clear()
    drawType.value = ''
    map.removeInteraction(draw)
  } else {
    if (drawType.value === 'line') {
      map.removeInteraction(draw)
      draw = new Draw({
        source: drawLayer.getSource(),
        type: 'LineString'
      })
    } else if (drawType.value === 'polygon') {
      map.removeInteraction(draw)
      draw = new Draw({
        source: drawLayer.getSource(),
        type: 'Polygon'
      })
    } else if (drawType.value === 'circle') {
      map.removeInteraction(draw)
      draw = new Draw({
        source: drawLayer.getSource(),
        type: 'Circle'
      })
    } else if (drawType.value === 'freehand') {
      map.removeInteraction(draw)
      draw = new Draw({
        type: 'LineString',
        source: drawLayer.getSource(),
        freehand: true
      })
    }
    map.addInteraction(draw)
  }
}

onMounted(async () => {
  map = new Map({
    target: 'map-container',
    view: new View({
      center: [114.25, 30.59],
      zoom: 4,
      projection: 'EPSG:4326'
    }),
    layers: [
      new TileLayer({
        source: new XYZ({
          url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
        })
      })
    ]
  })

  // 获取武汉市地理信息
  const temp = await fetch(`https://restapi.amap.com/v3/ip?ip=223.65.136.231&key=${GAODEKEY}`)
  const result = await temp.json()
  adcode.value = result.adcode
  searchCity.value = city.value = result.city
  // console.log(result)
  // https://geo.datav.aliyun.com/areas_v3/bound/420000.json
  const _temp = await fetch(`https://restapi.amap.com/v3/geocode/geo?key=${GAODEKEY}&address=${searchCity.value}`)
  const _result = await _temp.json()
  // console.log(_result)
  if(_result.status !== '0') {
    cityLocation.value = _result.geocodes[0].location.split(',').map(Number)
  }
  drawLayer = new VectorLayer({
    source: new VectorSource(),
    style: new Style({
      stroke: new Stroke({
        color: 'black',
        width: 2
      }),
      fill: new Fill({
        color: 'rgba(255, 0, 0, 0.5)'
      })
    })
  })
  map.addLayer(drawLayer)
  setTimeout(() => {
    cityLayer = new VectorLayer({
      className: 'city-layer',
      source: new VectorSource({
        url: `https://geo.datav.aliyun.com/areas_v3/bound/${adcode.value}.json`,
        format: new GeoJSON()
      }),
      style: new Style({
        stroke: new Stroke({
          color: 'black',
          widthL: 2
        }),
        fill: new Fill({
          color: 'rgba(255, 0, 0, 0.5)'
        })
      })
    })
    map.addLayer(cityLayer)
    if(cityLocation.value) {
      map.getView().animate({
        center: cityLocation.value,
        zoom: 8,
        duration: 2000
      })
    }
    map.getView().on('change:resolution', function(e) {
      const zoom = e.target.getZoom()
      if(zoom > 10) {
        cityLayer.setVisible(false)
        drawLayer.setVisible(false)
      } else {
        cityLayer.setVisible(true)
        drawLayer.setVisible(true)
      }
    })
    map.on('click', function(e) {
      const pixel = e.pixel
      const features = map.getFeaturesAtPixel(pixel)
      console.log(features)
      if(features.length > 0 && features[0].get('name')) {
        const feature = features[0]
        const { center, name, centroid } = feature.getProperties()
        // console.log(properties, name, centroid, center)
        popup = new Overlay({
          element: document.getElementById('pupop'),
          positioning: 'center-center'
        })
        popup.setPosition(center)
        popupContent.value = `
          <div>
            <h3>${name}</h3>
            <p>${centroid}</p>
          </div>
        `
        map.addOverlay(popup)
      } else {
        popup.setPosition(undefined)
      }
    })
  })
})
</script>

<style lang="scss" scoped>
.top-nav {
  height: 80px;
  background-color: blue;
  position: fixed;
  top: 0;
  width: calc(100% - 40px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  z-index: 999;
  color: white;
}

#map-container {
  width: 100%;
  height: calc(100vh - 80px);
  position: absolute;
  top: 80px;
}

#pupop {
  width: 200px;
  height: max-content;
  padding: 10px 20px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba($color: #000000, $alpha: .5);
  background-color: antiquewhite;
}
</style>